﻿using System;
using System.Configuration.Install;
using System.Reflection;
using System.ServiceProcess;
using System.IO;
using InstallerWinService.ServParsSite;
using System.Diagnostics;

namespace InstallerWinService
{
    class Program
    {
        static void Main(string[] args)//args[0] - параметр для дальнейшего действия, args[1] - clientid
        {
            string winservicename = "PharmClientService";
            string curdir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            string exeFileName = curdir + @"\" + winservicename + ".exe";
            string[] logFilesAll = Directory.GetFiles(curdir, "*.txt");
            foreach (string logFile in logFilesAll)
            {
                if (DateTime.Now.AddDays(-3) > File.GetCreationTime(logFile))
                    File.Delete(logFile);
            }
            LogFile logfile = new LogFile(curdir + @"\" + DateTime.Now.ToString("yyyyMMdd HH-mm-ss") + ".txt");
            try
            {
                logfile.WriteLine(exeFileName);
                if (File.Exists(exeFileName))
                {
                    //logfile.WriteLine("Имя службы\n " + winservicename);
                    logfile.WriteLine("Адрес службы\n " + exeFileName);
                    string res = "";
                    ServiceController sc;

                    while (true)
                    {
                        if (args.Length > 0)
                        {
                            if (args[0] == "-inst"
                                || args[0] == "-uninst"
                                || args[0] == "-close"
                                || args[0] == "-upd"
                                || args[0] == "-stop"
                                || args[0] == "-run"
                                || args[0] == "-inst_run")
                                res = args[0];
                        }

                        if (res == "") res = WriteHelp();

                        if (res == "-inst_run")
                        {
                            ManagedInstallerClass.InstallHelper(new[] { exeFileName });
                            logfile.WriteLine("Служба установлена");
                            sc = new ServiceController(winservicename);
                            logfile.WriteLine("Запуск службы");
                            sc.Start();
                            sc.WaitForStatus(ServiceControllerStatus.Running);
                            logfile.WriteLine("Служба запущена");
                            break;
                        }
                        if (res == "-inst")
                        {
                            ManagedInstallerClass.InstallHelper(new[] { exeFileName });
                            logfile.WriteLine("Служба установлена");
                            break;
                        }
                        if (res == "-run")
                        {
                            sc = new ServiceController(winservicename);
                            logfile.WriteLine("Запуск службы");
                            sc.Start();
                            sc.WaitForStatus(ServiceControllerStatus.Running);
                            logfile.WriteLine("Служба запущена");
                            break;
                        }
                        if (res == "-uninst")
                        {
                            try
                            {
                                sc = new ServiceController(winservicename);
                                logfile.WriteLine("Остановка службы");
                                sc.Stop();
                                sc.WaitForStatus(ServiceControllerStatus.Stopped);
                                logfile.WriteLine("Служба остановлена");
                            }
                            catch (Exception ex)
                            {
                                logfile.WriteLine("Исключение: " + ex.Message);
                            }
                            ManagedInstallerClass.InstallHelper(new[] { "/u", exeFileName });
                            logfile.WriteLine("Служба удалена");
                            break;
                        }
                        if (res == "-stop")
                        {
                            sc = new ServiceController(winservicename);
                            logfile.WriteLine("Остановка службы");
                            sc.Stop();
                            sc.WaitForStatus(ServiceControllerStatus.Stopped);
                            logfile.WriteLine("Служба остановлена");
                            break;
                        }
                        if (res == "-close")
                        {
                            logfile.WriteLine("Приложение закрыто без каких либо действий");
                            break;
                        }
                        if (res == "-upd")
                        {
                            sc = new ServiceController(winservicename);
                            logfile.WriteLine("Остановка службы");
                            sc.Stop();
                            sc.WaitForStatus(ServiceControllerStatus.Stopped);
                            logfile.WriteLine("Служба остановлена");
                            try
                            {
                                ServParsSiteClient client = new ServParsSiteClient();
                                FileNameVersion fnv = client.GetWinServiceInfo();
                                string currvers = FileVersionInfo.GetVersionInfo(exeFileName).FileVersion;

                                if (fnv.FileVersion != currvers)
                                {
                                    logfile.WriteLine("Загрузка обновлений");
                                    var chukscount = client.GetFileChunksCount(fnv.FileName);
                                    var stream = File.Create(exeFileName);
                                    for (var i = 0; i < chukscount; i++)
                                    {
                                        var chunk = client.GetFileChunk(fnv.FileName, i);
                                        var chunkBytes = Convert.FromBase64String(chunk);
                                        stream.Write(chunkBytes, 0, chunkBytes.Length);
                                    }
                                    stream.Close();
                                    logfile.WriteLine("Обновления загружены");
                                    client.ClientFileVersionUpd(Convert.ToInt32(args[1].Replace("-", "")), fnv.FileName, FileVersionInfo.GetVersionInfo(exeFileName).FileVersion);
                                }
                                else logfile.WriteLine("Актуальная версия службы уже установлена");
                            }
                            catch (Exception ex)
                            {
                                logfile.WriteLine("Исключение: " + ex.Message);
                            }
                            finally
                            {
                                logfile.WriteLine("Запуск службы");
                                sc.Start();
                                sc.WaitForStatus(ServiceControllerStatus.Running);
                                logfile.WriteLine("Служба запущена");
                            }
                            break;
                        }
                    }
                }
                else
                {
                    logfile.WriteLine("Отсутствует служба\n" + exeFileName);
                }
            }
            catch (Exception ex)
            {
                logfile.WriteLine("Исключение: " + ex.Message);
            }
            logfile.WriteLine("Остановка приложения");
            //Console.ReadKey();
        }

        static string WriteHelp()
        {
            Console.WriteLine("Параметры:");
            Console.WriteLine("-inst - установка службы");
            Console.WriteLine("-inst_run - установка и запуск службы");
            Console.WriteLine("-uninst - удаление службы");
            Console.WriteLine("-upd - обновление службы");
            Console.WriteLine("-stop - остановка службы");
            Console.WriteLine("-run - запуск службы");
            Console.WriteLine("-close - закрыть приложение");
            Console.WriteLine("Введите параметр: ");
            return Console.ReadLine();
        }
    }

    public class LogFile
    {
        StreamWriter sw;

        public LogFile(string path)
        {
            sw = new StreamWriter(path);
        }

        public void WriteLine(string str)
        {
            sw.WriteLine(str);
            sw.Flush();
        }
    }
}
